package com.saville.mc;

/*
 * Copyright 2008 Wink Saville
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.lang.Thread;
import java.net.*;
import java.io.*;
import java.net.ServerSocket;

import com.saville.debug.*;
import com.saville.msgcomp.IMc;
import com.saville.msgcomp.McConst;
import com.saville.msgcomp.Msg;

public class TcpMsgPipeConnectionServer implements Runnable {

    public static final int MCTCP_SERVER_GUID = -3;
    public static final int MCTCP_SERVER_CMD_CONNECTED = 0x10;

    /**
     * Constructor.
     * 
     * @param port to listen on
     * @param dstMc Mc to send connected messages too
     */
    public TcpMsgPipeConnectionServer(int port, IMc dstMc) {
        mName = "TcpMsgPipeConnectionServer-" + Timing.readTsc();
        Log.v(df, "%s: (); E port=%d", mName, port);

        mPort = port;
        mDstMc = dstMc;

        Log.v(df, "%s: (); X", mName);
    }

    /*
     * Start server
     * 
     * @return true of going
     */
    public boolean start() {
        Log.v(df, "%s: start(); X", mName);

        mThread = new Thread(null, this, mName);
        mThread.start();

        while (mServerRunning == 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
        }

        Log.v(df, "%s: start(); X mServerRunning=%d", mName, mServerRunning);

        return mServerRunning == 1;
    }

    public void run() {
        ServerSocket serverSocket;

        Log.v(df, "%s: run() E", mName);
        try {
            serverSocket = new ServerSocket(mPort);
        } catch (IOException e) {
            Log.e(df, "%s: error creating server socket on port=%d", mName, mPort);
            mServerRunning = 2;
            return;
        }

        mServerRunning = 1;
        while (mServerRunning == 1) {
            try {
                Log.v(df, "%s: wait for client", mName);
                Socket clientSocket = serverSocket.accept();
                Log.v(df, "%s: got a client", mName);
                Msg msg = new Msg();
                msg.guid = McConst.MCPIPE_GUID;
                msg.cmd = McConst.MCPIPE_CMD_CONNECTED;
                msg.obj = clientSocket;
                Log.v(df, "%s: queue a message to mDstMc", mName);
                mDstMc.queueMsg(msg);
            } catch (Exception e) {
                Log.e(df, "%s: Exception e=%s", mName, e);
            }
        }
        mServerRunning = 2;
        Log.e(df, "%s: Exiting very strange!!!", mName);
    }

    private int mPort;
    private Thread mThread;

    private IMc mDstMc;
    private int mServerRunning;
    private String mName;
    private int df = Log.ERROR;
}
